<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>Spring5学习笔记 | rongshen</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
  
  
<link rel="stylesheet" href="/css/style.css">

  
    
<link rel="stylesheet" href="/css/highlight.css">

  
  <meta name="description" content="Spring学习笔记">
<meta property="og:type" content="article">
<meta property="og:title" content="Spring5学习笔记">
<meta property="og:url" content="http://example.com/2020/07/26/Spring5%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/index.html">
<meta property="og:site_name" content="rongshen">
<meta property="og:description" content="Spring学习笔记">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726b1.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726b2.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726b3.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726b4.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726b5.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726b6.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726b7.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726b8.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726b9.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/image-20200721082031772.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/image-20200721082511662.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/image-20200721100200905.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/image-20200721100302953.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/image-20200721100448732.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/image-20200721105741754.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/image-20200721134056609.png">
<meta property="article:published_time" content="2020-07-26T07:57:37.000Z">
<meta property="article:modified_time" content="2021-05-07T06:46:00.411Z">
<meta property="article:author" content="John Doe">
<meta property="article:tag" content="spring">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://cdn.rongshen2020.com/20726b1.png"><meta name="generator" content="Hexo 6.1.0"></head>

<body>
  <div id="wrapper">
    <header id="header">
  <h1 id="title">
    <a href="/">rongshen</a>
  </h1>
  <nav>
    
    
      
      <a class="nav-link" href="/">Home</a>
    
      
        <span class="nav-spacer">×</span>
      
      <a class="nav-link" href="/archives">Archives</a>
    
      
        <span class="nav-spacer">×</span>
      
      <a class="nav-link" target="_blank" rel="noopener" href="https://github.com/Aaron-boom">Github</a>
    
      
        <span class="nav-spacer">×</span>
      
      <a class="nav-link" href="/2020/04/13/About-Me/">About</a>
    
    
  </nav>
</header>

    <div id="content">
      <article id="post-Spring5学习笔记" class="article article-type-post" itemprop="blogPost" itemscope>
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h2 class="article-title" itemprop="headline name">
      Spring5学习笔记
    </h2>
  


        <div class="article-meta">
          <time class="article-date" datetime="2020-07-26T07:57:37.000Z" itemprop="datePublished">2020-07-26</time>

          
        </div>
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
      
        <blockquote>
<p>Spring学习笔记</p>
</blockquote>
<span id="more"></span>

<h1 id="1、IoC"><a href="#1、IoC" class="headerlink" title="1、IoC"></a>1、IoC</h1><p>Spring的IoC(控制反转) 、DI(依赖注入)。</p>
<p><strong>Ioc—Inversion of Control，即“控制反转”，不是什么技术，而是一种设计思想。DI是实现IoC的一种方法。控制反转是一种设计思想。</strong></p>
<p>传统Java SE程序设计，我们直接在对象内部通过new进行创建对象，是程序主动去创建依赖对象；而IoC是有专门一个容器来创建这些对象，即由Ioc容器来控制对 象的创建。</p>
<p>写得很好的一篇博客：<a target="_blank" rel="noopener" href="https://www.cnblogs.com/xdp-gacl/p/4249939.html">https://www.cnblogs.com/xdp-gacl/p/4249939.html</a></p>
<p>spring官网：<a target="_blank" rel="noopener" href="https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/core.html#beans-annotation-config">https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/core.html#beans-annotation-config</a></p>
<ul>
<li>其实IoC对编程带来的最大改变不是从代码上，而是从思想上，发生了“主从换位”的变化。应用程序原本是老大，要获取什么资源都是主动出击，但是在IoC&#x2F;DI思想中，应用程序就变成被动的了，被动的等待IoC容器来创建并注入它所需要的资源了。IoC很好的体现了面向对象设计法则之一—— 好莱坞法则：“别找我们，我们找你”；即由IoC容器帮对象找相应的依赖对象并注入，而不是由对象主动去找。</li>
</ul>
<p><img src="http://cdn.rongshen2020.com/20726b1.png" alt="image-20200718211620579"></p>
<ul>
<li>从上面的图中我们也看到了中间件的影子。</li>
</ul>
<h2 id="1-1、如何实现IoC："><a href="#1-1、如何实现IoC：" class="headerlink" title="1.1、如何实现IoC："></a>1.1、如何实现IoC：</h2><p><strong>IoC是Spring框架的核心内容</strong>，使用多种方式完美的实现了IoC，可以使用XML配置，也可以使用注解，新版本的Spring也可以零配置实现IoC。</p>
<p>Spring容器在初始化时先读取配置文件，根据配置文件或元数据创建与组织对象存入容器中，程序使用时再从Ioc容器中取出需要的对象。</p>
<p><img src="http://cdn.rongshen2020.com/20726b2.png" alt="image-20200718211940110"></p>
<ul>
<li>采用XML方式配置Bean的时候，Bean的定义信息是和实现分离的，而采用注解的方式可以把两者合为一体，Bean的定义信息直接以注解的形式定义在实现类中，从而达到了零配置的目的。控制反转是一种通过描述（XML或注解）并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器，其实现方法是依赖注入（Dependency Injection,DI）。</li>
</ul>
<h2 id="1-2、HelloSpring："><a href="#1-2、HelloSpring：" class="headerlink" title="1.2、HelloSpring："></a>1.2、HelloSpring：</h2><ol>
<li><p>创建一个无模板的maven项目。</p>
</li>
<li><p>在该项目中在创建一个maven模块。可以添加spring或者springMVC的支持。或者直接创建一个SpringMVC的模块。</p>
</li>
<li><p>ApplicationContext.xml文件的大致样子：</p>
<pre><code class="java">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&gt;

    &lt;bean id=&quot;helloSpring&quot; class=&quot;com.aaron.pojo.Person&quot;&gt;
        &lt;!--在这里改变赋值就可以改变测试的输出--&gt;
        &lt;property name=&quot;name&quot; value=&quot;spring&quot;&gt;&lt;/property&gt;
    &lt;/bean&gt;
    
&lt;/beans&gt;
</code></pre>
</li>
<li><p>测试使用：</p>
<pre><code class="JAVA">import com.aaron.pojo.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.TestConstructor;

public class Test &#123;
    public static void main(String[] args) &#123;
        ApplicationContext context = new ClassPathXmlApplicationContext(&quot;ApplicationContext.xml&quot;);
        Person helloSpring = (Person) context.getBean(&quot;helloSpring&quot;);
        helloSpring.toString();
    &#125;

&#125;
</code></pre>
</li>
</ol>
<h1 id="2、IoC创建对象的方式"><a href="#2、IoC创建对象的方式" class="headerlink" title="2、IoC创建对象的方式"></a>2、IoC创建对象的方式</h1><ol>
<li><p>默认使用无参构造创建对象。</p>
</li>
<li><p>假设我们需要使用有参构造来创建对象。可以使用注入构造器：</p>
<p>参考文档：<a target="_blank" rel="noopener" href="https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/core.html#beans-dependencies">https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/core.html#beans-dependencies</a></p>
<ol>
<li>第一种，参数下标赋值：</li>
</ol>
<pre><code class="java">例如你的构造函数是：
    public class Person &#123;
        public Person(String name) &#123;
            this.name = name;
        &#125;
    &#125;

那么index就是你有参方法里面的参数的下标，从0开始：
&lt;bean id=&quot;exampleBean&quot; class=&quot;examples.ExampleBean&quot;&gt;
    &lt;constructor-arg index=&quot;0&quot; value=&quot;aaron荣燊&quot;/&gt;
&lt;/bean&gt;
</code></pre>
<ol start="2">
<li>第二种，参数类型赋值：</li>
</ol>
<pre><code class="JAVA">&lt;bean id=&quot;exampleBean&quot; class=&quot;examples.ExampleBean&quot;&gt;
    &lt;constructor-arg type=&quot;java.lang.String&quot; value=&quot;aaron荣燊&quot;/&gt;
&lt;/bean&gt;
</code></pre>
<ol start="3">
<li>第三种，参数名来赋值：</li>
</ol>
<pre><code class="java">&lt;bean id=&quot;exampleBean&quot; class=&quot;examples.ExampleBean&quot;&gt;
    &lt;constructor-arg name=&quot;name&quot; value=&quot;aaron荣燊&quot;/&gt;
&lt;/bean&gt;
</code></pre>
</li>
</ol>
<p>总结：在配置文件加载的时候，容器中管理的对象就已经初始化了！而且是单例的。。。就是相同的对象只创建一个。</p>
<h1 id="3、Spring配置"><a href="#3、Spring配置" class="headerlink" title="3、Spring配置"></a>3、Spring配置</h1><h2 id="3-1、别名："><a href="#3-1、别名：" class="headerlink" title="3.1、别名："></a>3.1、别名：</h2><pre><code class="java">&lt;bean id=&quot;helloSpring&quot; class=&quot;com.aaron.pojo.Person&quot;&gt;
        &lt;!--在这里改变赋值就可以改变测试的输出--&gt;
        &lt;property name=&quot;name&quot; value=&quot;hello spring&quot;&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;alias name=&quot;helloSpring&quot; alias=&quot;jj&quot;&gt;&lt;/alias&gt;
 
//使用
public class Test &#123;
    public static void main(String[] args) &#123;
        ApplicationContext context = new ClassPathXmlApplicationContext(&quot;ApplicationContext.xml&quot;);
        Person helloSpring = (Person) context.getBean(&quot;jj&quot;);
        helloSpring.show();
    &#125;
</code></pre>
<h2 id="3-2、Bean的配置："><a href="#3-2、Bean的配置：" class="headerlink" title="3.2、Bean的配置："></a>3.2、Bean的配置：</h2><pre><code class="java">id：bean的唯一标识符，也就是相当于我们学的对象名
class：bean对象所对应的权限定名，包名+类型
name：通过name也可以取别名，而且那么可以取多个别名。
scope：是否是单例模式
    
&lt;bean id=&quot;helloSpring&quot; class=&quot;com.aaron.pojo.Person&quot; name=&quot;jj jj1,jj2;jj3&quot; scope=&quot;prototype&quot;&gt;
        &lt;!--在这里改变赋值就可以改变测试的输出--&gt;
        &lt;property name=&quot;name&quot; value=&quot;hello spring&quot;&gt;&lt;/property&gt;
    &lt;/bean&gt;
</code></pre>
<h2 id="3-3、import："><a href="#3-3、import：" class="headerlink" title="3.3、import："></a>3.3、import：</h2><ul>
<li><p>一般用于团队开发使用，他可以将多个xml配置文件导入合并为一个。</p>
</li>
<li><p>applicationContext.xml：</p>
</li>
</ul>
<pre><code class="java">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&gt;

    &lt;bean id=&quot;helloSpring&quot; class=&quot;com.aaron.pojo.Person&quot;&gt;
        &lt;!--在这里改变赋值就可以改变测试的输出--&gt;
        &lt;property name=&quot;name&quot; value=&quot;hello spring&quot;&gt;&lt;/property&gt;
    &lt;/bean&gt;

    &lt;alias name=&quot;helloSpring&quot; alias=&quot;jj&quot;&gt;&lt;/alias&gt;

&lt;/beans&gt;
</code></pre>
<ul>
<li>bean.xml：</li>
</ul>
<pre><code class="java">&lt;import resource=&quot;applicationContext.xml&quot;&gt;
&lt;import resource=&quot;applicationContext1.xml&quot;&gt;
&lt;import resource=&quot;applicationContext2.xml&quot;&gt;
</code></pre>
<p>后期直接使用总的bean.xml配置文件就可以了。</p>
<h1 id="4、DI依赖注入"><a href="#4、DI依赖注入" class="headerlink" title="4、DI依赖注入"></a>4、DI依赖注入</h1><h2 id="4-1、构造器注入："><a href="#4-1、构造器注入：" class="headerlink" title="4.1、构造器注入："></a>4.1、构造器注入：</h2><p>前面已经讲过了。</p>
<h2 id="4-2、Set方式注入【重点】："><a href="#4-2、Set方式注入【重点】：" class="headerlink" title="4.2、Set方式注入【重点】："></a>4.2、Set方式注入【重点】：</h2><ul>
<li>依赖：bean对象的创建依赖于容器</li>
<li>注入：bean对象中的所有属性，由容器来注入。</li>
<li>例：</li>
</ul>
<ol>
<li><p>项目构造：</p>
<p><img src="http://cdn.rongshen2020.com/20726b3.png" alt="image-20200719131600188"></p>
</li>
<li><p>Address.java：</p>
<pre><code class="java">package com.aaron.pojo;

public class Address &#123;
    private String address;

    public String getAddress() &#123;
        return address;
    &#125;

    public void setAddress(String address) &#123;
        this.address = address;
    &#125;

    @Override
    public String toString() &#123;
        return &quot;Address&#123;&quot; +
                &quot;address=&#39;&quot; + address + &#39;\&#39;&#39; +
                &#39;&#125;&#39;;
    &#125;
&#125;
</code></pre>
</li>
<li><p>Student.java：</p>
<pre><code class="java">package com.aaron.pojo;

import java.util.*;

public class Student &#123;
    private String name;
    private Address address;
    private String[] books;
    private List&lt;String&gt; hobbys;
    private Map&lt;String,String&gt; card;
    private Set&lt;String&gt; games;
    private String wife;
    private Properties info;

    public String getName() &#123;
        return name;
    &#125;

    public void setName(String name) &#123;
        this.name = name;
    &#125;

    public Address getAddress() &#123;
        return address;
    &#125;

    public void setAddress(Address address) &#123;
        this.address = address;
    &#125;

    public String[] getBooks() &#123;
        return books;
    &#125;

    public void setBooks(String[] books) &#123;
        this.books = books;
    &#125;

    public List&lt;String&gt; getHobbys() &#123;
        return hobbys;
    &#125;

    public void setHobbys(List&lt;String&gt; hobbys) &#123;
        this.hobbys = hobbys;
    &#125;

    public Map&lt;String, String&gt; getCard() &#123;
        return card;
    &#125;

    public void setCard(Map&lt;String, String&gt; card) &#123;
        this.card = card;
    &#125;

    public Set&lt;String&gt; getGames() &#123;
        return games;
    &#125;

    public void setGames(Set&lt;String&gt; games) &#123;
        this.games = games;
    &#125;

    public String getWife() &#123;
        return wife;
    &#125;

    public void setWife(String wife) &#123;
        this.wife = wife;
    &#125;

    public Properties getInfo() &#123;
        return info;
    &#125;

    public void setInfo(Properties info) &#123;
        this.info = info;
    &#125;

    @Override
    public String toString() &#123;
        return &quot;Student&#123;&quot; +
                &quot;name=&#39;&quot; + name + &#39;\&#39;&#39; +
                &quot;, address=&quot; + address.toString() +
                &quot;, books=&quot; + Arrays.toString(books) +
                &quot;, hobbys=&quot; + hobbys +
                &quot;, card=&quot; + card +
                &quot;, games=&quot; + games +
                &quot;, wife=&#39;&quot; + wife + &#39;\&#39;&#39; +
                &quot;, info=&quot; + info +
                &#39;&#125;&#39;;
    &#125;
&#125;
</code></pre>
</li>
<li><p>bean.xml：</p>
<pre><code class="java">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&gt;

    &lt;bean id=&quot;address1&quot; class=&quot;com.aaron.pojo.Address&quot;&gt;
        &lt;property name=&quot;address&quot; value=&quot;江西九江&quot;&gt;&lt;/property&gt;
    &lt;/bean&gt;

    &lt;bean name=&quot;student&quot; class=&quot;com.aaron.pojo.Student&quot;&gt;
        &lt;!-- 第一种，普通值注入，使用value --&gt;
        &lt;property name=&quot;name&quot; value=&quot;荣燊&quot;&gt;&lt;/property&gt;

        &lt;!-- 第二种，bean注入，使用ref --&gt;
        &lt;property name=&quot;address&quot; ref=&quot;address1&quot;&gt;&lt;/property&gt;

        &lt;!-- String数组注入--&gt;
        &lt;property name=&quot;books&quot;&gt;
            &lt;array&gt;
                &lt;value&gt;红楼梦&lt;/value&gt;
                &lt;value&gt;西游记&lt;/value&gt;
                &lt;value&gt;三国演义&lt;/value&gt;
                &lt;value&gt;水浒传&lt;/value&gt;
            &lt;/array&gt;
        &lt;/property&gt;

        &lt;!-- List数组注入--&gt;
        &lt;property name=&quot;hobbys&quot;&gt;
            &lt;list&gt;
                &lt;value&gt;唱歌&lt;/value&gt;
                &lt;value&gt;看电影&lt;/value&gt;
                &lt;value&gt;写代码&lt;/value&gt;
                &lt;value&gt;运动&lt;/value&gt;
            &lt;/list&gt;
        &lt;/property&gt;

        &lt;!-- Map数组注入--&gt;
        &lt;property name=&quot;card&quot;&gt;
            &lt;map&gt;
                &lt;entry key=&quot;身份证&quot; value=&quot;123123123123123123&quot;/&gt;
                &lt;entry key=&quot;银行卡&quot; value=&quot;1231231231231231234567&quot;/&gt;
            &lt;/map&gt;
        &lt;/property&gt;

        &lt;!-- Set注入--&gt;
        &lt;property name=&quot;games&quot;&gt;
            &lt;set&gt;
                &lt;value&gt;LOL&lt;/value&gt;
                &lt;value&gt;COC&lt;/value&gt;
            &lt;/set&gt;
        &lt;/property&gt;

        &lt;!-- NULL空字符串注入--&gt;
        &lt;property name=&quot;wife&quot;&gt;
            &lt;null/&gt;
        &lt;/property&gt;

        &lt;!-- Properties注入--&gt;
        &lt;property name=&quot;info&quot;&gt;
            &lt;props&gt;
                &lt;prop key=&quot;学号&quot;&gt;1467002030&lt;/prop&gt;
                &lt;prop key=&quot;性别&quot;&gt;男&lt;/prop&gt;
                &lt;prop key=&quot;姓名&quot;&gt;小明&lt;/prop&gt;
                &lt;prop key=&quot;userName&quot;&gt;root&lt;/prop&gt;
                &lt;prop key=&quot;passWord&quot;&gt;root&lt;/prop&gt;
            &lt;/props&gt;
        &lt;/property&gt;

    &lt;/bean&gt;
&lt;/beans&gt;
</code></pre>
</li>
<li><p>Mytest.java：</p>
<pre><code class="java">import com.aaron.pojo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest &#123;
    public static void main(String[] args) &#123;
        ApplicationContext context = new ClassPathXmlApplicationContext(&quot;bean.xml&quot;);
        Student student = (Student) context.getBean(&quot;student&quot;);
        System.out.println(student.toString());
    &#125;
&#125;
</code></pre>
</li>
<li><p>输出：</p>
<p><img src="http://cdn.rongshen2020.com/20726b4.png" alt="image-20200719131957489"></p>
</li>
</ol>
<h2 id="4-3、拓展方式注入："><a href="#4-3、拓展方式注入：" class="headerlink" title="4.3、拓展方式注入："></a>4.3、拓展方式注入：</h2><p>说明：p命名空间像之前的直接注入，c命名空间注入像通过一个有参构造器注入。p命名空间与c命名空间都不能直接使用，需要导入xml约束。</p>
<ul>
<li><h3 id="p命名空间导入："><a href="#p命名空间导入：" class="headerlink" title="p命名空间导入："></a>p命名空间导入：</h3></li>
</ul>
<ol>
<li>命名头：</li>
</ol>
<pre><code class="java">xmlns:p=&quot;http://www.springframework.org/schema/p&quot;
</code></pre>
<ol start="2">
<li>实体类User.java：</li>
</ol>
<pre><code class="java">package com.aaron.pojo;

public class User &#123;
    private String userName;
    private int age;
    
    @Override
    public String toString() &#123;
        return &quot;User&#123;&quot; +
                &quot;userName=&#39;&quot; + userName + &#39;\&#39;&#39; +
                &quot;, age=&quot; + age +
                &#39;&#125;&#39;;
    &#125;

    public String getUserName() &#123;
        return userName;
    &#125;

    public void setUserName(String userName) &#123;
        this.userName = userName;
    &#125;

    public int getAge() &#123;
        return age;
    &#125;

    public void setAge(int age) &#123;
        this.age = age;
    &#125;
&#125;
</code></pre>
<ol start="2">
<li>xml文件中就可以这样写：</li>
</ol>
<pre><code class="java">&lt;!-- p命名空间可以直接注入同样的值，property --&gt;
&lt;bean id=&quot;user&quot; class=&quot;com.aaron.pojo.User&quot; p:userName=&quot;夏天&quot; p:age=&quot;18&quot;/&gt;
</code></pre>
<ul>
<li><h3 id="c命名空间导入："><a href="#c命名空间导入：" class="headerlink" title="c命名空间导入："></a>c命名空间导入：</h3></li>
</ul>
<p>注意，该命名空间是要求  实体类里面  写了有参构造器的。</p>
<ol>
<li>命名头：</li>
</ol>
<pre><code>xmlns:c=&quot;http://www.springframework.org/schema/c&quot;
</code></pre>
<ol start="2">
<li>实体类中需要写   有参构造器  ：</li>
</ol>
<pre><code class="java">package com.aaron.pojo;

public class User &#123;
    private String userName;
    private int age;

    //可以在这里写一个无参构造器，那么p命名空间也可以用了
    
    public User(String userName, int age) &#123;
        this.userName = userName;
        this.age = age;
    &#125;

    @Override
    public String toString() &#123;
        return &quot;User&#123;&quot; +
                &quot;userName=&#39;&quot; + userName + &#39;\&#39;&#39; +
                &quot;, age=&quot; + age +
                &#39;&#125;&#39;;
    &#125;

    public String getUserName() &#123;
        return userName;
    &#125;

    public void setUserName(String userName) &#123;
        this.userName = userName;
    &#125;

    public int getAge() &#123;
        return age;
    &#125;

    public void setAge(int age) &#123;
        this.age = age;
    &#125;
&#125;
</code></pre>
<ol start="2">
<li>xml文件中就可以这样写：</li>
</ol>
<pre><code class="java">&lt;bean id=&quot;user&quot; class=&quot;com.aaron.pojo.User&quot; c:userName=&quot;谢磊&quot; c:age=&quot;25&quot; /&gt;
</code></pre>
<h1 id="5、bean的作用域scope"><a href="#5、bean的作用域scope" class="headerlink" title="5、bean的作用域scope"></a>5、bean的作用域scope</h1><p><img src="http://cdn.rongshen2020.com/20726b5.png" alt="image-20200719161622482"></p>
<h2 id="5-1、singleton单例："><a href="#5-1、singleton单例：" class="headerlink" title="5.1、singleton单例："></a>5.1、singleton单例：</h2><p>默认实现用这种。</p>
<h2 id="5-2、prototyp原型："><a href="#5-2、prototyp原型：" class="headerlink" title="5.2、prototyp原型："></a>5.2、prototyp原型：</h2><p>也就是多例。每次从容器中get的时候，都会产生一个新对象。</p>
<ol>
<li><p>配置：</p>
<pre><code class="java">&lt;bean id=&quot;user&quot; class=&quot;com.aaron.pojo.User&quot; c:userName=&quot;谢磊&quot; c:age=&quot;25&quot; scope=&quot;prototype&quot;/&gt;
</code></pre>
</li>
<li><p>使用：<br><img src="http://cdn.rongshen2020.com/20726b6.png" alt="image-20200719162229863"></p>
</li>
</ol>
<h2 id="5-3、其余："><a href="#5-3、其余：" class="headerlink" title="5.3、其余："></a>5.3、其余：</h2><p>其余的像request、session、application这些只能在web开发中使用到。</p>
<h1 id="6、Bean的自动装配"><a href="#6、Bean的自动装配" class="headerlink" title="6、Bean的自动装配"></a>6、Bean的自动装配</h1><ul>
<li>自动装配是spring满足bean依赖的一种方式。</li>
<li>spring会在上下文context中自动寻找，并自动给bean装配属性。</li>
</ul>
<p>在spring中有三种装配的方式</p>
<ol>
<li>在xml中显示的配置</li>
<li>在java中显示的配置</li>
<li>隐式的自动装配bean【重要】</li>
</ol>
<h2 id="6-1、-Autowired："><a href="#6-1、-Autowired：" class="headerlink" title="6.1、@Autowired："></a>6.1、@Autowired：</h2><h3 id="6-1-1、byName自动装配："><a href="#6-1-1、byName自动装配：" class="headerlink" title="6.1.1、byName自动装配："></a>6.1.1、byName自动装配：</h3><ul>
<li><p>byName会自动在容器上下文中查找，和自己对象set方法后面的值对饮的bean的id。id是要小写的。</p>
<pre><code class="java">&lt;bean id=&quot;cat&quot; class=&quot;com.aaron.pojo.Cat&quot;/&gt;
&lt;bean id=&quot;dog&quot; class=&quot;com.aaron.pojo.Dog&quot;/&gt;  //id必须小写，与people里的对应
&lt;bean id=&quot;dog1&quot; class=&quot;com.aaron.pojo.Dog&quot;/&gt;  //错误
&lt;bean id=&quot;Dog&quot; class=&quot;com.aaron.pojo.Dog&quot;/&gt;  //错误

&lt;bean id=&quot;people&quot; class=&quot;com.aaron.pojo.People&quot; autowire=&quot;byName&quot;&gt;
    &lt;property name=&quot;name&quot; value=&quot;谢蕾蕾&quot;/&gt;
&lt;/bean&gt;
</code></pre>
</li>
</ul>
<h3 id="6-1-2、byType自动装配："><a href="#6-1-2、byType自动装配：" class="headerlink" title="6.1.2、byType自动装配："></a>6.1.2、byType自动装配：</h3><ul>
<li><p>byName会自动在容器上下文中查找，和自己对象属性类型相同的bean。类型必须唯一。</p>
<pre><code class="java">&lt;bean id=&quot;cat&quot; class=&quot;com.aaron.pojo.Cat&quot;/&gt;
&lt;bean id=&quot;dog111&quot; class=&quot;com.aaron.pojo.Dog&quot;/&gt;  
&lt;bean class=&quot;com.aaron.pojo.Dog&quot;/&gt; //不用id也可以
&lt;bean id=&quot;dog&quot; class=&quot;com.aaron.pojo.Dog&quot;/&gt; //错误，和上面的定义只能有一个在
    
&lt;bean id=&quot;people&quot; class=&quot;com.aaron.pojo.People&quot; autowire=&quot;byType&quot;&gt;
    &lt;property name=&quot;name&quot; value=&quot;谢蕾蕾&quot;/&gt;
&lt;/bean&gt;
</code></pre>
</li>
</ul>
<h3 id="6-1-3、小结："><a href="#6-1-3、小结：" class="headerlink" title="6.1.3、小结："></a>6.1.3、小结：</h3><ul>
<li>byName的时候，需要保证所有的bean的id唯一，并且这个bean需要和自动注入的属性的set方法的值一致。</li>
<li>byType的时候，需要保证所有的bean的class唯一，并且这个bean需要和自动注入的属性的类型一致。</li>
</ul>
<h2 id="6-2、注解实现自动装配："><a href="#6-2、注解实现自动装配：" class="headerlink" title="6.2、注解实现自动装配："></a>6.2、注解实现自动装配：</h2><p>jdk1.5支持注解，spring2.5就开始支持注解。</p>
<p>要使用注解：</p>
<ol>
<li><p>导入约束，context约束。</p>
</li>
<li><p>配置注解的支持</p>
<pre><code class="java">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
    xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd&quot;&gt;

    &lt;context:annotation-config/&gt;

&lt;/beans&gt;
</code></pre>
</li>
<li><p>直接在属性上使用即可，也可以在set方法上使用。使用Autowired我们可以不用写set方法了，前提是你这个自动装配的属性在IOC容器中存在。：</p>
<pre><code class="java">@Autowired
private Cat cat;
@Autowired
private Dog dog;


&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd&quot;&gt;

    &lt;context:annotation-config/&gt;

    &lt;bean id=&quot;cat&quot; class=&quot;com.aaron.pojo.Cat&quot;/&gt;
    &lt;bean id=&quot;dog&quot; class=&quot;com.aaron.pojo.Dog&quot;/&gt;
    &lt;bean id=&quot;people&quot; class=&quot;com.aaron.pojo.People&quot; autowire=&quot;byName&quot;/&gt;

&lt;/beans&gt;
</code></pre>
</li>
<li><p>科普：</p>
<pre><code class="java">@Nullable 字段标记了这个注解，说明这个字段可以为null；

@Autowired(required = false) //里面的值可以为空，null    
@Qualifier(value=&quot;dog&quot;) //多个装配相同的对象，可以和autowired搭配使用
    
@Resource //java的原生注解
</code></pre>
</li>
</ol>
<ul>
<li><p>小结：</p>
<p>@Resource和@Autowired的区别：</p>
<pre><code>1. 都是用来自动装配的，都可以放在属性字段上
 2. @Autowired通过byType的方式实现，而且必须要求这个对象存在。
 3. @Resource默认通过byName的方式实现，如果找不到名字，则通过byType实现。
</code></pre>
</li>
</ul>
<h1 id="7、使用注解开发"><a href="#7、使用注解开发" class="headerlink" title="7、使用注解开发"></a>7、使用注解开发</h1><p>在spring4之后要使用注解开发，必须导入AOP的包了。使用注解需要导入context的约束，增加注解的支持。</p>
<pre><code class="java">//指定要扫描的包，这个包下面的注解就会生效
&lt;context:component-scan base-package=&quot;com.aaron.pojo&quot;/&gt; 
</code></pre>
<p>@Component：组件，放在类上，说明这个类被Spring管理了，就是bean。</p>
<h2 id="7-1、bean："><a href="#7-1、bean：" class="headerlink" title="7.1、bean："></a>7.1、bean：</h2><pre><code class="java">//该注解等价于&lt;bean id=&quot;user&quot; class=&quot;com.aaron.pojo.User&quot;/&gt;
//注册组件
@Component
public class User &#123;
    @Value(&quot;夏天&quot;)
    public String name;
&#125;
</code></pre>
<h2 id="7-2、属性如何注入："><a href="#7-2、属性如何注入：" class="headerlink" title="7.2、属性如何注入："></a>7.2、属性如何注入：</h2><pre><code class="java">//相当于&lt;property name=&quot;name&quot; value=&quot;夏天&quot;/&gt;，也可以注解在set方法上
@Value(&quot;夏天&quot;)
public String name;

//或者
@Value(&quot;夏天&quot;)
public void setName(String name) &#123;
    this.name = name;
&#125;
</code></pre>
<h2 id="7-3、衍生的注解："><a href="#7-3、衍生的注解：" class="headerlink" title="7.3、衍生的注解："></a>7.3、衍生的注解：</h2><p>@Component有几个衍生注解，我们在web开发中，会按照mvc三层架构分层。</p>
<ul>
<li>dao层：<code>@Repository</code></li>
<li>service层：<code>@Service</code></li>
<li>controller{servlet}层：<code>@Controller</code></li>
<li>这四个注解都是代表将某个类注册到Spring中，装配bean。</li>
</ul>
<h2 id="7-4、自动装配："><a href="#7-4、自动装配：" class="headerlink" title="7.4、自动装配："></a>7.4、自动装配：</h2><pre><code class="java">@Nullable 字段标记了这个注解，说明这个字段可以为null；

@Autowired(required = false) //里面的值可以为空，null    
@Qualifier(value=&quot;dog&quot;) //多个装配相同的对象，可以和autowired搭配使用
    
@Resource //java的原生注解
</code></pre>
<h2 id="7-5、作用域："><a href="#7-5、作用域：" class="headerlink" title="7.5、作用域："></a>7.5、作用域：</h2><p>@Scope</p>
<pre><code class="java">@Component
@Scope(&quot;prototype&quot;)
public class User &#123;
    public String name;
&#125;
</code></pre>
<h2 id="7-6、小结："><a href="#7-6、小结：" class="headerlink" title="7.6、小结："></a>7.6、小结：</h2><p>比较xml配置文件与注解：</p>
<ul>
<li>xml更加万能，适用于任何场合！维护更加方便。</li>
<li>注解，不是自己的类使用不了，维护相对复杂。</li>
</ul>
<p>xml与注解的最佳实践：</p>
<ul>
<li>xml用来管理bean。</li>
<li>注解只负责完成属性的注入。</li>
</ul>
<p>我们在使用的过程中，只需要注意一个问题：让注解生效，必须开启注解的支持。</p>
<pre><code class="java">&lt;context:annotation-config/&gt;
&lt;context:component-scan base-package=&quot;com.aaron.pojo&quot;/&gt;
</code></pre>
<h1 id="8、使用java的方式配置Spring"><a href="#8、使用java的方式配置Spring" class="headerlink" title="8、使用java的方式配置Spring"></a>8、使用java的方式配置Spring</h1><p>我们现在不使用Spring中xml的配置方式了，交给java来做。</p>
<p>JavaConfig是Spring的一个子项目，在spring4之后，他称为了一个新功能。</p>
<p><img src="http://cdn.rongshen2020.com/20726b7.png" alt="image-20200719210501430"></p>
<p><img src="http://cdn.rongshen2020.com/20726b8.png" alt="image-20200719210538628"></p>
<p>这种纯java的注解在spingboot中随处可见。所以springboot很重要。</p>
<h1 id="9、代理模式proxy"><a href="#9、代理模式proxy" class="headerlink" title="9、代理模式proxy"></a>9、代理模式proxy</h1><h2 id="9-1、静态代理："><a href="#9-1、静态代理：" class="headerlink" title="9.1、静态代理："></a>9.1、静态代理：</h2><p>角色分析：</p>
<ul>
<li>抽象角色：一般会使用接口或者抽象类来解决 </li>
<li>真实角色：被代理的角色</li>
<li>代理角色：代理真实角色，代理真实角色之后，我们一般会做一些附属操作</li>
<li>客户：访问代理对象的人</li>
</ul>
<p>代理模式的好处：</p>
<ul>
<li>可以使真实角色的操作更加纯粹，不用去关注一些公共的业务（例如日志功能 ）。</li>
<li>公共业务也就交给代理角色，实现了业务的分工。</li>
<li>公共业务发生扩展的时候，方便集中管理。</li>
</ul>
<p>缺点：</p>
<ul>
<li>一个真实角色就会产生一个代理角色，代码量就会翻倍，开发效率会更低</li>
</ul>
<h2 id="9-2、动态代理："><a href="#9-2、动态代理：" class="headerlink" title="9.2、动态代理："></a>9.2、动态代理：</h2><ul>
<li>动态代理和静态代理角色一样</li>
<li>动态代理的代理类是动态生成的，不是我们直接写好的。</li>
<li>动态代理分为两大类：<strong>1.基于接口的动态代理，2.基于类的动态代理。</strong><ul>
<li>基于接口——JDK代理</li>
<li>基于类的——cglib</li>
<li>java字节码实现——javasist</li>
</ul>
</li>
</ul>
<p>需要了解两个类：Proxy代理，InvocationHandler调用处理程序。</p>
<p><strong>动态代理的好处：</strong></p>
<ul>
<li>可以使真实角色的操作可以更加纯粹！不用去关注一些公共的业务。</li>
<li>公共业务就交给代理角色！实现了业务的分工。</li>
<li>公共业务发生扩展的时候，方便集中管理。</li>
<li>一个动态代理类代理的就是一个接口，一般就是对应的一类业务。</li>
<li>一个动态代理类可以代理多个类，只要是实现了同一个接口即可。</li>
</ul>
<p><strong>实例：</strong></p>
<ol>
<li><p>UserService接口:</p>
<pre><code class="java">package com.aaron.proxyDemo;

public interface UserService &#123;
    //接口里面的类
    public void add();
    public void delete();
    public void update();
    public void query();
&#125;
</code></pre>
</li>
<li><p>UserService接口实现类UserServiceImpl：</p>
<pre><code>package com.aaron.proxyDemo;

public class UserServiceImpl implements UserService &#123;

    public void add() &#123;
        System.out.println(&quot;新增一个用户~&quot;);
    &#125;

    public void delete() &#123;
        System.out.println(&quot;删除一个用户~&quot;);
    &#125;

    public void update() &#123;
        System.out.println(&quot;修改一个用户~&quot;);
    &#125;

    public void query() &#123;
        System.out.println(&quot;查询一个用户~&quot;);
    &#125;

&#125;
</code></pre>
</li>
<li><p>ProxyInvocationHandler自动生成代理类：</p>
<pre><code>package com.aaron.proxyDemo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//等会我们会用这个类，自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler &#123;

    //被代理的接口
    private Object target;

    public void setTarget(Object target) &#123;
        this.target = target;
    &#125;

    //生成得到代理类
    public Object getProxy()&#123;
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                target.getClass().getInterfaces(),this);
    &#125;

    //处理代理实例，并返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable &#123;
        log(method.getName());
        Object result = method.invoke(target, args);
        return result;
    &#125;

    public void log(String msg)&#123;
        System.out.println(&quot;调用了&quot;+msg+&quot;方法&quot;);
    &#125;
&#125;
</code></pre>
</li>
<li><p>测试方法：</p>
<pre><code>package com.aaron.proxyDemo;

public class Client &#123;
    public static void main(String[] args) &#123;
        //真实角色
        UserServiceImpl userService = new UserServiceImpl();
        //代理角色
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        //设置要代理的对象
        pih.setTarget(userService);
        //动态生成代理类
        UserService proxy = (UserService) pih.getProxy();
        proxy.add();
        proxy.delete();
        proxy.update();
        proxy.query();
    &#125;
&#125;
</code></pre>
</li>
</ol>
<h1 id="10、AOP"><a href="#10、AOP" class="headerlink" title="10、AOP"></a>10、AOP</h1><h2 id="10-1、什么是AOP："><a href="#10-1、什么是AOP：" class="headerlink" title="10.1、什么是AOP："></a>10.1、什么是AOP：</h2><p> 在软件业，AOP为Aspect Oriented Programming的缩写，意为：面向切面编程，通过<strong>预编译方式和运行期间动态代理</strong>实现程序功能的统一维护的一种技术。</p>
<p><strong>AOP的几个专业术语：</strong></p>
<ul>
<li><p>横切关注点：</p>
</li>
<li><p>通知方法：（就像日志工具类LogUtils里面的LogStart、LogReturn等等方法）</p>
</li>
<li><p>切面类：（就像日志工具类LogUtils）</p>
</li>
<li><p>连接点：每一个方法的每一个位置就是一个连接点。</p>
</li>
<li><p>切入点：红色部分，我们真正需要执行日志记录的地方。</p>
</li>
<li><p>图见：</p>
<p><img src="http://cdn.rongshen2020.com/20726b9.png" alt="img"></p>
</li>
</ul>
<p><img src="http://cdn.rongshen2020.com/image-20200721082031772.png" alt="image-20200721082031772"></p>
<h2 id="10-2、AOP在Spring中的作用："><a href="#10-2、AOP在Spring中的作用：" class="headerlink" title="10.2、AOP在Spring中的作用："></a>10.2、AOP在Spring中的作用：</h2><p><img src="http://cdn.rongshen2020.com/image-20200721082511662.png" alt="image-20200721082511662"></p>
<h2 id="10-3、使用Spring实现AOP："><a href="#10-3、使用Spring实现AOP：" class="headerlink" title="10.3、使用Spring实现AOP："></a>10.3、使用Spring实现AOP：</h2><h3 id="10-3-1、使用Spring的API接口实现："><a href="#10-3-1、使用Spring的API接口实现：" class="headerlink" title="10.3.1、使用Spring的API接口实现："></a>10.3.1、使用Spring的API接口实现：</h3><ol>
<li><p>使用到的jar包（有些包应该也不是必须的）：</p>
<p><img src="http://cdn.rongshen2020.com/image-20200721100200905.png" alt="image-20200721100200905"></p>
</li>
<li><p>项目结构：</p>
<p><img src="http://cdn.rongshen2020.com/image-20200721100302953.png" alt="image-20200721100302953"></p>
</li>
<li><p>各类、接口、方法与xml配置：</p>
<ul>
<li><p>UserService接口与UserServiceImpl实现方法：</p>
<pre><code class="java">//UserService.java
package com.aaron.service;

public interface UserService &#123;
    public void add();
    public void delete();
    public void update();
    public void query();
&#125;

//UserServiceImpl.java
package com.aaron.service;

public class UserServiceImpl implements UserService &#123;
    public void add() &#123;
        System.out.println(&quot;增加了一个用户~&quot;);
    &#125;

    public void delete() &#123;
        System.out.println(&quot;删除了一个用户~&quot;);
    &#125;

    public void update() &#123;
        System.out.println(&quot;修改了一个用户~&quot;);
    &#125;

    public void query() &#123;
        System.out.println(&quot;查询了一个用户~&quot;);
    &#125;
&#125;
</code></pre>
</li>
<li><p>接口方法实现前执行的Log：</p>
<pre><code class="java">package com.aaron.log;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class Log implements MethodBeforeAdvice &#123;

    //method：要执行的目标对象的方法
    //args：参数
    //target：目标对象
    public void before(Method method, Object[] args, Object target) throws Throwable &#123;
        System.out.println(target.getClass().getName()+&quot;目标对象的&quot;+method.getName()+&quot;方法被执行了&quot;);
    &#125;

&#125;
</code></pre>
</li>
<li><p>接口方法实现后执行的LogAfter：</p>
<pre><code class="java">package com.aaron.log;

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

public class LogAfter implements AfterReturningAdvice &#123;

    //o：返回结果
    //objects：参数
    //o1：目标对象
    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable &#123;
        System.out.println(&quot;执行了&quot;+method.getName()+&quot;方法，返回结果为：&quot;+o);
    &#125;

&#125;
</code></pre>
</li>
<li><p>beans.xml：</p>
<pre><code class="java">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd&quot;&gt;

    &lt;!--注册bean--&gt;
    &lt;bean id=&quot;userService&quot; class=&quot;com.aaron.service.UserServiceImpl&quot;/&gt;
    &lt;bean id=&quot;log&quot; class=&quot;com.aaron.log.Log&quot;/&gt;
    &lt;bean id=&quot;logAfter&quot; class=&quot;com.aaron.log.LogAfter&quot;/&gt;

    &lt;!--方式一：使用原生的Spring API接口--&gt;
    &lt;!--配置AOP，需要导入aop的约束--&gt;
    &lt;aop:config&gt;
        &lt;!--切入点，expression表达式，要执行的位置execution(修饰词 返回值 类名 方法名 参数)--&gt;
        &lt;aop:pointcut id=&quot;pointcut&quot; expression=&quot;execution(* com.aaron.service.UserServiceImpl.*(..))&quot;/&gt;

        &lt;!--执行环绕增加，将log这个类加到id为pointcut的切入点上--&gt;
        &lt;aop:advisor advice-ref=&quot;log&quot; pointcut-ref=&quot;pointcut&quot;&gt;&lt;/aop:advisor&gt;
        &lt;aop:advisor advice-ref=&quot;logAfter&quot; pointcut-ref=&quot;pointcut&quot;/&gt;
    &lt;/aop:config&gt;

&lt;/beans&gt;
</code></pre>
</li>
</ul>
</li>
<li><p>测试类：</p>
<pre><code class="java">import com.aaron.service.UserService;
import com.aaron.service.UserServiceImpl;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest &#123;
    public static void main(String[] args)  &#123;
        ApplicationContext context = new ClassPathXmlApplicationContext(&quot;beans.xml&quot;);
        //动态代理代理的是个接口，注意点
        UserService userService = (UserService) context.getBean(&quot;userService&quot;);
        userService.add();
    &#125;
&#125;
</code></pre>
</li>
<li><p>输出：</p>
<p><img src="http://cdn.rongshen2020.com/image-20200721100448732.png" alt="image-20200721100448732"></p>
</li>
</ol>
<h3 id="10-3-2、自定义类来实现："><a href="#10-3-2、自定义类来实现：" class="headerlink" title="10.3.2、自定义类来实现："></a>10.3.2、自定义类来实现：</h3><p>基于以上的测试类不变，新增一个diy的类，xml文件里的写法也要改变：</p>
<ul>
<li><p>diy的类：</p>
<pre><code class="java">package com.aaron.diy;

public class DiyPointcut &#123;
    public void before()&#123;
        System.out.println(&quot;方法执行前————————&quot;);
    &#125;

    public void after()&#123;
        System.out.println(&quot;方法执行后————————&quot;);
    &#125;
&#125;
</code></pre>
</li>
<li><p>beans.xml：</p>
<pre><code class="java">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd&quot;&gt;

    &lt;!--注册bean--&gt;
    &lt;bean id=&quot;userService&quot; class=&quot;com.aaron.service.UserServiceImpl&quot;/&gt;
    &lt;bean id=&quot;diy&quot; class=&quot;com.aaron.diy.DiyPointcut&quot;/&gt;

    &lt;!--方法二，自定义类--&gt;
    &lt;aop:config&gt;
        &lt;!--自定义切面，ref要使用的类--&gt;
        &lt;aop:aspect ref=&quot;diy&quot;&gt;
            &lt;!--切入点--&gt;
            &lt;aop:pointcut id=&quot;point&quot; expression=&quot;execution(* com.aaron.service.UserServiceImpl.*(..))&quot;/&gt;
            &lt;!--通知--&gt;
            &lt;aop:before method=&quot;before&quot; pointcut-ref=&quot;point&quot;/&gt;
            &lt;aop:after method=&quot;after&quot; pointcut-ref=&quot;point&quot;/&gt;
        &lt;/aop:aspect&gt;
    &lt;/aop:config&gt;

&lt;/beans&gt;
</code></pre>
</li>
<li><p>测试类不变，结果为：</p>
<p><img src="http://cdn.rongshen2020.com/image-20200721105741754.png" alt="image-20200721105741754"></p>
</li>
</ul>
<h3 id="10-3-3、使用注解实现："><a href="#10-3-3、使用注解实现：" class="headerlink" title="10.3.3、使用注解实现："></a>10.3.3、使用注解实现：</h3><ul>
<li><p>先标记切入类和切入方法：</p>
<pre><code class="java">package com.aaron.annotation;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

//标记类是一个切面
@Aspect
public class AnnotationPointCut &#123;

    @Before(&quot;execution(* com.aaron.service.UserServiceImpl.*(..))&quot;)
    public void before()&#123;
        System.out.println(&quot;方法执行前——————&quot;);
    &#125;

    @After(&quot;execution(* com.aaron.service.UserServiceImpl.*(..))&quot;)
    public void after()&#123;
        System.out.println(&quot;方法执行后——————&quot;);
    &#125;

    //在环绕增强的时候，我们可以给定一个参数，代表我们要获取处理切入的点
    @Around(&quot;execution(* com.aaron.service.UserServiceImpl.*(..))&quot;)
    public void around(ProceedingJoinPoint pjp) throws Throwable &#123;
        System.out.println(&quot;环绕前&quot;);
        pjp.proceed();
        System.out.println(&quot;环绕后&quot;);
    &#125;
&#125;
</code></pre>
</li>
<li><p>beans.xml中注册：</p>
<pre><code class="java">&lt;bean id=&quot;userService&quot; class=&quot;com.aaron.service.UserServiceImpl&quot;/&gt;
&lt;bean id=&quot;annotionPointCut&quot; class=&quot;com.aaron.annotation.AnnotationPointCut&quot;/&gt;
</code></pre>
</li>
<li><p>测试类不变，测试结果：</p>
<p><img src="http://cdn.rongshen2020.com/image-20200721134056609.png" alt="image-20200721134056609"></p>
</li>
</ul>

      
    </div>
    
    
    <div class="article-category">
      
        <b>Categories:</b>
        <a class="article-category-link" href="/categories/%E6%A1%86%E6%9E%B6/">框架</a>
      
      
        <br/>
      
      
        <b>Tags:</b>
        <a class="article-tag-none-link" href="/tags/spring/" rel="tag">spring</a>
      
    </div>
    
    
  </div>
</article>

  
<nav id="article-nav" class="article-nav">
  
    <a href="/2020/09/02/springBoot%E9%9B%86%E6%88%90shiro%E5%AE%89%E5%85%A8%E6%A1%86%E6%9E%B6/" id="article-nav-newer" class="article-nav-link-wrap newer">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          springBoot集成shiro安全框架
        
      </div>
    </a>
  
  
    <a href="/2020/07/26/mybatis3%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" id="article-nav-older" class="article-nav-link-wrap older">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">
        
          mybatis3学习笔记
        
      </div>
    </a>
  
</nav>






    </div>
  </div>
  




<div id="settings-container">
  <div id="dark-mode">dark</div>
  <div id="sans-font">sans</div>
</div>
<script type="text/javascript">
let d=document,r=d.documentElement.style,f=r.setProperty.bind(r),l=localStorage,s=l.getItem('s')||(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches),n=l.getItem('n'),m=d.getElementById("dark-mode"),b=()=>{f('--bg-color','#fafafa');f('--code-bg-color','#f4f4f4');f('--text-color','#212121');f('--secondary-color','#808080');f('--tertiary-color','#b0b0b0');f('--link-color','#b5c8cf');f('--link-hover-color','#618794');f('--link-bg-color','#dae4e7');f('--selection-color','#dae4e7');m.innerHTML="dark"},c=()=>{f('--bg-color','#212121');f('--code-bg-color','#292929');f('--text-color','#fff');f('--secondary-color','#c0c0c0');f('--tertiary-color','#6e6e6e');f('--link-color','#4d6b75');f('--link-hover-color','#96b1bb');f('--link-bg-color','#5d828e');f('--selection-color','#acc1c9');m.innerHTML="light"},o=d.getElementById("sans-font"),e=()=>{f('--body-stack','"Lora", "Georgia", "Times New Roman", serif');o.innerHTML="sans"},g=()=>{f('--body-stack','"Lato", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", "Verdana", sans-serif');o.innerHTML="serif"};m.onclick=()=>{if(s==2){s=1;l.setItem('s',s);c()}else{s=2;l.setItem('s',s);b()}};o.onclick=()=>{if(n==2){n=1;l.setItem('n',n);g()}else{n=2;l.setItem('n',n);e()}};if(!s){s=2;l.setItem('s',2)};if(s==1){c()};if(!n){n=2;l.setItem('n',2)};if(n==1){g()};
</script>




</body>
</html>
